#!/usr/bin/env python

##########################################################################
#  Copyright (C) 2007 Robert Connolly <rob_connolly@mailshack.com>       #
#                                                                        #
#  This program is free software; you can redistribute it and/or modify  #
#  it under the terms of the GNU General Public License as published by  #
#  the Free Software Foundation; either version 3 of the License, or     #
#  (at your option) any later version. See file COPYING for details.     #
#                                                                        #
#  This program is distributed in the hope that it will be useful,       #
#  but WITHOUT ANY WARRANTY; without even the implied warranty of        #
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         #
#  GNU General Public License for more details.                          #
#                                                                        #
#  You should have received a copy of the GNU General Public License     #
#  along with this program; if not, write to the                         #
#  Free Software Foundation, Inc.,                                       #
#  59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             #
##########################################################################

import sys
import gobject, gtk, gconf

import dbus, dbus.service
if getattr(dbus, 'version', (0,0,0)) >= (0,41,0):
	import dbus.glib
	
sys.path.append('..')

class Daemon(dbus.service.Object):
	displays = {}

	def __init__(self):
		bus = dbus.SessionBus()
		name = dbus.service.BusName('com.googlecode.cairolets', bus=bus)
		
        	dbus.service.Object.__init__(self, name, '/Daemon')
        	
        	self.client = gconf.client_get_default()
        	self.client.add_dir('/apps/cairolets/daemon', gconf.CLIENT_PRELOAD_NONE)
        	
        	saved = self.client.get_list('/apps/cairolets/daemon/saved_displays', gconf.VALUE_STRING)
        	for s in saved:
        		self.add_desklet(s)
        	
        	try:
        		gtk.main()
        	except KeyboardInterrupt:
        		self.__cleanup()
        		
	@dbus.service.method(dbus_interface='com.googlecode.cairolets.Daemon', in_signature='s', out_signature='a{sv}')
	def add_desklet(self, dname):
		ret = {}
		if dname in self.displays:
			ret['message'] = "Display '%s' is already running!" % dname
			ret['status'] = False
		else:
			d = self.__load_display(dname)
			d.connect("daemon-quit", self.__quit)
			d.connect("display-quit", self.__clean_display)
			d.run()
		
			self.displays[dname] = d
			self.client.set_list('/apps/cairolets/daemon/saved_displays', gconf.VALUE_STRING, self.displays.keys())
		
			ret['status'] = True
			
		return ret
		
	@dbus.service.method(dbus_interface='com.googlecode.cairolets.Daemon', in_signature='s', out_signature='a{sv}')
	def remove_desklet(self, dname):
		ret = {}
		if dname in self.displays:
			self.displays[dname].quit()
			self.client.set_list('/apps/cairolets/daemon/saved_displays', gconf.VALUE_STRING, self.displays.keys())
			ret['status'] = True
		else:
			ret['message'] = "Display '%s' is not running!" % dname
			ret['status'] = False
			
		return ret
		
	@dbus.service.method(dbus_interface='com.googlecode.cairolets.Daemon', in_signature='', out_signature='as')
	def list_desklets(self):
		return self.displays.keys()
		
	@dbus.service.method(dbus_interface='com.googlecode.cairolets.Daemon', in_signature='', out_signature='b')
	def kill(self):
		self.__quit(None)
		return True
		
	def __load_display(self, dname):
		name = "cairolets.displays."+dname
		mod = __import__(name)
	    	components = name.split('.')
	    	for comp in components[1:]:
	        	mod = getattr(mod, comp)
	        mod = getattr(mod, dname)
		return mod(dname)
		
	def __cleanup(self):
		while True:
			try:
				(dname, d) = self.displays.popitem()
				d.quit()
			except KeyError:
				break
				
	def __clean_display(self, widget, dname):
		if dname in self.displays:
			del self.displays[dname]
		
	def __quit(self, desklet):
		save = self.displays.keys()
		self.__cleanup()
		gtk.main_quit()
		self.client.set_list('/apps/cairolets/daemon/saved_displays', gconf.VALUE_STRING, save)

if __name__ == "__main__":
	Daemon()
	
